package com.xms.queryview.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.xms.core.exception.XmsException;
import com.xms.datacore.service.UpdaterService;
import com.xms.event.core.AuthorizationStateChangedEvent;
import com.xms.event.core.IEventPublisher;
import com.xms.queryview.core.QueryViewDefaults;
import com.xms.queryview.entity.QueryView;
import com.xms.utils.CollectionUtil;
import com.xms.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * QueryviewUpdaterService
 * </p>
 *
 * @author migo
 * @since 2021/9/3
 */
@CacheConfig(cacheNames = "queryview", keyGenerator = "CacheKeyGenerator")
@Service
public class QueryViewUpdaterService extends UpdaterService<QueryView> implements IQueryViewUpdaterService {
    private IEventPublisher _eventPublisher;
    private IQueryViewDependency _queryViewDependency;

    @Autowired
    public QueryViewUpdaterService(IEventPublisher eventPublisher,
                                   IQueryViewDependency queryViewDependency) {
        _eventPublisher = eventPublisher;
        _queryViewDependency = queryViewDependency;
    }

    @CacheEvict(allEntries = true, condition = "#result == true")
    @Transactional(rollbackFor=Exception.class)
    @Override
    public boolean update(QueryView entity) throws XmsException, SQLException {
        //压缩json
        entity.setFetchconfig(StringUtil.compress(entity.getFetchconfig()));
        entity.setLayoutconfig(StringUtil.compress(entity.getLayoutconfig()));
        entity.setAggregateconfig(StringUtil.compress(entity.getAggregateconfig()));
        boolean success = super.updateById(entity);
        if (success) {
            //依赖项
            _queryViewDependency.update(entity);
        }
        return success;
    }

    @CacheEvict(allEntries = true, condition = "#result == true")
    @Transactional(rollbackFor=Exception.class)
    @Override
    public boolean updateMany(List<QueryView> entity) throws XmsException, SQLException {
        if (CollectionUtil.isEmpty(entity))
            return false;
        for (QueryView item : entity) {
            this.update(item);
        }
        return true;
    }

    @CacheEvict(allEntries = true, condition = "#result == true")
    @Override
    public boolean updateDefault(UUID entityId, UUID id) {
        //更新原有数据为非默认
        LambdaUpdateWrapper<QueryView> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(QueryView::getIsdefault, false).eq(QueryView::getEntityid, entityId);
        super.update(updateWrapper);
        //再设置本ID的记录为默认
        LambdaUpdateWrapper<QueryView> updateWrapper2 = new LambdaUpdateWrapper<>();
        updateWrapper2.set(QueryView::getIsdefault, true)
                .eq(QueryView::getQueryviewid, id);
        boolean success = super.update(updateWrapper2);
        if(success) {
            //默认项要发送权限更改事件
            _eventPublisher.publish(new AuthorizationStateChangedEvent(QueryViewDefaults.MODULE_NAME, Collections.singletonList(id), false));
        }
        return success;
    }

    @CacheEvict(allEntries = true, condition = "#result == true")
    @Override
    public boolean updateState(boolean isEnabled, List<UUID> id) {
        Assert.notEmpty(id, "id must not be empty");
        LambdaUpdateWrapper<QueryView> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(QueryView::getStatecode, isEnabled)
                .in(QueryView::getQueryviewid, id);
        return super.update(updateWrapper);
    }

    @CacheEvict(allEntries = true, condition = "#result == true")
    @Override
    public boolean updateAuthorization(boolean isAuthorization, List<UUID> id) {
        Assert.notEmpty(id, "id must not be empty");
        LambdaUpdateWrapper<QueryView> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(QueryView::getAuthorizationenabled, isAuthorization)
                .in(QueryView::getQueryviewid, id);
        boolean success = super.update(updateWrapper);
        if (success) {
            _eventPublisher.publish(new AuthorizationStateChangedEvent(QueryViewDefaults.MODULE_NAME, id, isAuthorization));
        }
        return success;
    }
}
